package com.hua.utility.utility;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UtilValidate {

	public static final String className = UtilValidate.class.getName();

	public static final String digits = "0123456789";

	public static final String digitsHex = digits + "abcdefABCDEF";

	public static final String lettersLowercase = "abcdefghijklmnopqrstuvwxyz";

	public static final String letterSuppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

	public static final String letters = lettersLowercase + letterSuppercase;

	public static final String lettersWhitespace = " \t\n\r";

	public static final String decimalPointDelimiter = ".";

	public static final String phoneNumberDelimiters = "()- ";

	public static final String phoneChars = digits + phoneNumberDelimiters;

	public static final String zipCodeChars = digits;

	public static final int zipCodeLength = 6;

	public static final String creditCardDelimiters = " -";

	public static final String CityStateCodes = "";

	public static final String dateFormatString = "yyyy-MM-dd";

	public static final String timeFormatString = "HH-mm-ss";

	public static final String patternMobile = "^(((\\+?86)|(\\(\\+86\\)))?((13[0-9]{1})|(15[0-9]{1})|(17[0-9]{1})|(18[0-9]{1}))+\\d{8})$";

	public static final String patternPhone = "^\\d{3,4}-?\\d{7,9}$";

	public static final String patternQqNumber = "^[1-9][0-9]{4,12}$";

	public static final String patternUrl = "^(((https|http|ftp|rtsp|mms):[\\\\/\\\\/]{2}){1}[^\\\\s]+)|(((https|http|ftp|rtsp|mms):[\\\\/\\\\/]{2})?[a-zA-Z]{1}[a-zA-Z0-9\\\\-_]*(\\\\.[a-z]{2,5}){1}[^\\\\s]?+)$";

	public static final String patternEmail = "^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?$";

	public static final String patternIP = "^(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])$";

	public static final String patternChinese = "^[\\u4e00-\\u9fa5]$";

	public static final String patternDoubleByte = "^[^\\x00-\\xff]$";

	public static final String patternWeixin = "^[a-zA-Z]+[a-zA-Z0-9_]+$";

	@SuppressWarnings("rawtypes")
	private static boolean isEmpty(Object o) {
		Boolean checkResult = false;
		if (o == null) {
			checkResult = true;
		} else if (o instanceof String) {
			if ((o.toString().trim()).length() <= 0) {
				checkResult = true;
			}
		} else if (o instanceof java.util.Collection) {
			if (((java.util.Collection) o).size() <= 0) {
				checkResult = true;
			}
		} else if (o instanceof java.util.Map) {
			if (((java.util.Map) o).size() <= 0) {
				checkResult = true;
			}
		} else if (o instanceof java.lang.CharSequence) {
			if (((java.lang.CharSequence) o).length() <= 0) {
				checkResult = true;
			}
		} else {
			try {
				o.toString();
			} catch (Exception e) {
				throwRuntimeException(o.getClass().getName() + "toString forbidden operation.");
			}
		}
		return checkResult;
	}

	private static void throwRuntimeException(Object o) {
		if (isEmpty(o)) {
			return;
		} else if (o instanceof Throwable) {
			throw new RuntimeException(className + ":" + ((Throwable) o).getMessage());
		} else {
			throw new RuntimeException(className + ":" + o.toString());
		}
	}

	public static boolean checkEqual(Object o1, Object o2) {
		if (o1 == null) {
			return o2 == null;
		} else {
			return o1.equals(o2);
		}
	}

	public static boolean checkNumberRange(Number number, Number min, Number max, boolean beforeInclude,
			boolean afterInclude) {
		boolean result = true;
		BigDecimal oBigDecimal = new BigDecimal(number.doubleValue());
		if (Double.isInfinite(min.doubleValue()) || Double.isNaN(min.doubleValue())) {
			min = null;
		}
		if (Double.isInfinite(max.doubleValue()) || Double.isNaN(max.doubleValue())) {
			max = null;
		}
		if (!isEmpty(min)) {
			BigDecimal minBigDecimal = new BigDecimal(min.doubleValue());
			if (oBigDecimal.compareTo(minBigDecimal) < (beforeInclude ? 0 : 1)) {
				result = false;
			}
		}
		if (!isEmpty(max)) {
			BigDecimal maxBigDecimal = new BigDecimal(max.doubleValue());
			if (oBigDecimal.compareTo(maxBigDecimal) > (afterInclude ? 0 : -1)) {
				result = false;
			}
		}
		return result;
	}

	public static boolean checkStringLength(String str, Integer min, Integer max, boolean beforeInclude,
			boolean afterInclude) {
		boolean result = true;
		if (isEmpty(str)) {
			result = false;
		} else {
			int length = str.length();
			if (!isEmpty(min)) {
				if (beforeInclude) {
					result = length >= min;
				} else {
					result = length > min;
				}
			}
			if (!isEmpty(max)) {
				if (afterInclude) {
					result = length <= max;
				} else {
					result = length < max;
				}
			}
		}
		return result;
	}

	// base type operation
	public static boolean isString(Object o) {
		boolean result = false;
		if (o != null && o instanceof java.lang.String) {
			result = true;
		}
		return result;
	}

	public static boolean isWhitespace(String str) {
		boolean result = true;
		if (isEmpty(str)) {
			result = true;
		} else {
			for (int i = 0; i < str.length(); i++) {
				char c = str.charAt(i);
				if (lettersWhitespace.indexOf(c) == -1) {
					result = false;
					break;
				}
			}
		}
		return result;
	}

	public static String removeCharsInBag(String s, String bag) {
		StringBuilder stringBuilder = new StringBuilder("");
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (bag.indexOf(c) == -1)
				stringBuilder.append(c);
		}
		return stringBuilder.toString();
	}

	public static String removeCharsNotInBag(String s, String bag) {
		StringBuilder stringBuilder = new StringBuilder("");
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (bag.indexOf(c) != -1)
				stringBuilder.append(c);
		}
		return stringBuilder.toString();
	}

	public static String removeWhitespace(String s) {
		return removeCharsInBag(s, lettersWhitespace);
	}

	public static boolean charInString(char c, String s) {
		return (s.indexOf(c) != -1);
	}

	public static String trim(String s) {
		if (isEmpty(s)) {
			return null;
		}
		return s.trim();
	}

	public static String trimAll(String s) {
		if (isEmpty(s)) {
			return null;
		}
		return removeCharsInBag(s, " ");
	}

	public static String trimStart(String s) {
		if (isEmpty(s)) {
			return null;
		}
		int len = s.length();
		int st = 0;
		char[] val = s.toCharArray();

		while ((st < len) && (val[st] <= ' ')) {
			st++;
		}
		return ((st > 0) || (len < s.length())) ? s.substring(st, len) : s;
	}

	public static String trimEnd(String s) {
		if (isEmpty(s)) {
			return null;
		}
		int len = s.length();
		int st = 0;
		char[] val = s.toCharArray();
		while ((st < len) && (val[len - 1] <= ' ')) {
			len--;
		}
		return ((st > 0) || (len < s.length())) ? s.substring(st, len) : s;
	}

	public static boolean isLetter(char c) {
		return Character.isLetter(c);
	}

	public static boolean isUpperLetter(char c) {
		return Character.isUpperCase(c);
	}

	public static boolean isLowerLetter(char c) {
		return Character.isLowerCase(c);
	}

	public static boolean isDigit(char c) {
		return Character.isDigit(c);
	}

	public static boolean isLetterOrDigit(char c) {
		return Character.isLetterOrDigit(c);
	}

	public static boolean isHexDigit(char c) {
		return digitsHex.indexOf(c) >= 0;
	}

	public static boolean isChinese(char s) {
		boolean result = false;
		if (!isEmpty(s)) {
			String target = String.valueOf(s);
			if (target.length() != 0) {
				Pattern pattern = Pattern.compile(patternChinese);
				Matcher matcher = pattern.matcher(target);
				result = matcher.matches();
			}
		}
		return result;
	}

	public static boolean isChinese(String s) {
		if (isEmpty(s))
			return false;
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (!isChinese(c))
				return false;
		}
		return true;
	}

	public static boolean isDoubleByte(char s) {
		boolean result = false;
		if (!isEmpty(s)) {
			String target = String.valueOf(s);
			if (target.length() != 0) {
				Pattern pattern = Pattern.compile(patternDoubleByte);
				Matcher matcher = pattern.matcher(target);
				result = matcher.matches();
			}
		}
		return result;
	}

	public static boolean isDoubleByte(String s) {
		if (isEmpty(s))
			return false;
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (!isDoubleByte(c))
				return false;
		}
		return true;
	}

	public static boolean isDigit(String s) {
		if (isEmpty(s))
			return false;
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (!isDigit(c))
				return false;
		}
		return true;
	}

	public static boolean isByte(String s) {
		if (isEmpty(s))
			return false;
		try {
			Byte.parseByte(s);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	public static boolean isShort(String s) {
		if (isEmpty(s))
			return false;
		try {
			Short.parseShort(s);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	public static boolean isInteger(String s) {
		if (isEmpty(s))
			return false;
		try {
			Integer.parseInt(s);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	public static boolean isLong(String s) {
		if (isEmpty(s))
			return false;
		try {
			Long.parseLong(s);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	public static boolean isFloat(String s) {
		if (isEmpty(s))
			return false;
		try {
			Float.parseFloat(s);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	public static boolean isDouble(String s) {
		if (isEmpty(s))
			return false;
		try {
			Double.parseDouble(s);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	public static boolean isCharacter(String s) {
		if (s == null)
			return false;
		try {
			if (s.toCharArray().length == 1) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			return false;
		}
	}

	public static boolean isBoolean(String s) {
		return true;
	}

	public static boolean isNumber(String s) {
		return isDouble(s);
	}

	public static boolean isNumberPositive(String s) {
		if (isEmpty(s) || !isNumber(s))
			return false;
		try {
			Double temp = Double.parseDouble(s);
			if (temp > 0) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			return false;
		}
	}

	public static boolean isNumberNonnegative(String s) {
		if (isEmpty(s) || !isNumber(s))
			return false;
		try {
			Double temp = Double.parseDouble(s);
			if (temp >= 0) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			return false;
		}
	}

	public static boolean isNumberNegative(String s) {
		if (isEmpty(s) || !isNumber(s))
			return false;
		try {
			Double temp = Double.parseDouble(s);
			if (temp < 0) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			return false;
		}
	}

	public static boolean isNumberNonpositive(String s) {
		if (isEmpty(s) || !isNumber(s))
			return false;
		try {
			Double temp = Double.parseDouble(s);
			if (temp <= 0) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			return false;
		}
	}

	public static boolean isAlphabetic(String s) {
		if (isEmpty(s))
			return false;
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (!isLetter(c))
				return false;
		}
		return true;
	}

	public static boolean isUpperAlphabetic(String s) {
		if (isEmpty(s))
			return false;
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (!isUpperLetter(c))
				return false;
		}
		return true;
	}

	public static boolean isLowerAlphabetic(String s) {
		if (isEmpty(s))
			return false;
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (!isLowerLetter(c))
				return false;
		}
		return true;
	}

	public static boolean isAlphanumeric(String s) {
		if (isEmpty(s))
			return false;
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (!isLetterOrDigit(c))
				return false;
		}
		return true;
	}

	// date time operation
	public static boolean isIntegerInRange(String s, int min, int max) {
		if (isEmpty(s) || !isInteger(s)) {
			return false;
		} else {
			return checkNumberRange(new BigDecimal(s), min, max, true, true);
		}
	}

	public static boolean isYearNumber(String s) {
		return isIntegerInRange(s, 0, 9999);
	}

	public static boolean isLeapYear(String s) {
		boolean result = false;
		if (isYearNumber(s)) {
			result = isLeapYear(Integer.parseInt(s));
		}
		return result;
	}

	public static boolean isLeapYear(int year) {
		boolean result = false;
		if (isYearNumber(String.valueOf(year))) {
			result = (((year % 4 == 0) && ((!(year % 100 == 0)) || (year % 400 == 0))) ? true : false);
		}
		return result;
	}

	public static boolean isMonthNumber(String s) {
		return isIntegerInRange(s, 1, 12);
	}

	public static boolean isDayNumber(String s) {
		return isIntegerInRange(s, 1, 31);
	}

	public static boolean isHourNumber(String s) {
		return isIntegerInRange(s, 0, 23);
	}

	public static boolean isMinuteNumber(String s) {
		return isIntegerInRange(s, 0, 59);
	}

	public static boolean isSecondNumber(String s) {
		return isIntegerInRange(s, 0, 59);
	}

	public static boolean isMilliSecondNumber(String s) {
		return isIntegerInRange(s, 0, 999);
	}

	public static boolean isDate(String yearStr, String monthStr, String dayStr) {
		int[] daysInMonth = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

		if (!(isYearNumber(yearStr) && isMonthNumber(monthStr) && isDayNumber(dayStr))) {
			return false;
		}
		int intMonth = Integer.parseInt(monthStr);
		int intDay = Integer.parseInt(dayStr);
		if (intDay > daysInMonth[intMonth - 1])
			return false;
		if ((intMonth == 2) && (intDay > (isLeapYear(yearStr) ? 29 : 28)))
			return false;
		return true;
	}

	public static Date getDate(String dateString, String formatString) {
		if (isEmpty(dateString) || isEmpty(formatString)) {
			return null;
		} else {
			DateFormat dateFormat = new SimpleDateFormat(formatString);
			try {
				return dateFormat.parse(dateString);
			} catch (ParseException e) {
				return null;
			}
		}
	}

	public static boolean isDate(String dateString, String formatString) {
		if (isEmpty(formatString)) {
			formatString = dateFormatString;
		}
		Date date = getDate(dateString, formatString);
		if (isEmpty(date)) {
			return false;
		} else {
			return true;
		}
	}

	public static boolean isDate(String dateString) {
		return isDate(dateString, null);
	}

	public static boolean isTime(String hour, String minute, String second) {
		return isHourNumber(hour) && isMinuteNumber(minute) && isSecondNumber(second);
	}

	public static boolean isTime(String timeString, String formatString) {
		if (isEmpty(formatString)) {
			formatString = timeFormatString;
		}
		Date time = getDate(timeString, formatString);
		if (isEmpty(time)) {
			return false;
		} else {
			return true;
		}
	}

	public static boolean isTime(String timeString) {
		return isTime(timeString, null);
	}

	// common type operation
	private static String getPhoneNumberInternationalString(String s) {
		String result = s;
		if (!isEmpty(s)) {
			String normalized = removeCharsInBag(s, phoneNumberDelimiters);
			if (normalized.length() > 0 && normalized.contains("+")) {
				normalized = normalized.substring(1);
			}
			result = normalized;
		}
		return result;
	}

	public static boolean isPhoneNumberInternational(String s) {
		boolean result = false;
		String normalized = getPhoneNumberInternationalString(s);
		if (isEmpty(normalized)) {
			result = false;
		} else {
			result = isDigit(normalized);
		}
		return result;
	}

	public static boolean isPhoneNumberUS(String s) {
		boolean result = isPhoneNumberInternational(s);
		if (result) {
			String normalized = getPhoneNumberInternationalString(s);
			if (normalized.length() == 0) {
				result = false;
			} else {
				result = (normalized.length() == 7) || (normalized.length() == 9);
			}
		}
		return result;
	}

	public static boolean isPhoneNumberMobile(String s) {
		boolean result = isPhoneNumberInternational(s);
		if (result) {
			String normalized = getPhoneNumberInternationalString(s);
			if (normalized.length() == 0 || !isDigit(normalized)) {
				result = false;
			} else {
				Pattern pattern = Pattern.compile(patternMobile);
				Matcher matcher = pattern.matcher(normalized);
				result = matcher.matches();
			}
		}
		return result;
	}

	public static boolean isPhoneNumberPhone(String s) {
		boolean result = isPhoneNumberInternational(s);
		if (result) {
			String normalized = getPhoneNumberInternationalString(s);
			if (normalized.length() == 0 || !isDigit(normalized)) {
				result = false;
			} else {
				Pattern pattern = Pattern.compile(patternPhone);
				Matcher matcher = pattern.matcher(normalized);
				result = matcher.matches();
			}
		}
		return result;
	}

	public static boolean isPhoneNumber(String s) {
		return isPhoneNumberMobile(s) || isPhoneNumberPhone(s);
	}

	public static boolean isUrl(String s) {
		boolean result = false;
		if (!isEmpty(s)) {
			String target = s.trim();
			if (target.length() != 0) {
				Pattern pattern = Pattern.compile(patternUrl);
				Matcher matcher = pattern.matcher(target);
				result = matcher.matches();
			}
		}
		return result;
	}

	public static boolean isEmail(String s) {
		boolean result = false;
		if (!isEmpty(s)) {
			String target = s.trim();
			if (target.length() != 0) {
				Pattern pattern = Pattern.compile(patternEmail);
				Matcher matcher = pattern.matcher(target);
				result = matcher.matches();
			}
		}
		return result;
	}

	public static boolean isPort(String s) {
		return isIntegerInRange(s, 0, 65536);
	}

	public static boolean isIP(String s) {
		boolean result = false;
		if (!isEmpty(s)) {
			String target = s.trim();
			if (target.length() != 0) {
				Pattern pattern = Pattern.compile(patternIP);
				Matcher matcher = pattern.matcher(target);
				result = matcher.matches();
			}
		}
		return result;
	}

	public static boolean isZipCode(String s) {
		if (isEmpty(s))
			return false;
		String normalized = removeCharsInBag(s, "- ");
		return (isDigit(normalized) && (normalized.length() == zipCodeLength));
	}

	public static boolean isQqNumber(String s) {
		boolean result = false;
		if (!isEmpty(s)) {
			String target = s.trim();
			if (target.length() != 0) {
				Pattern pattern = Pattern.compile(patternQqNumber);
				Matcher matcher = pattern.matcher(target);
				result = matcher.matches();
			}
		}
		return result;
	}

	public static boolean isWeixinNumber(String s) {
		boolean result = false;
		if (!isEmpty(s)) {
			String target = s.trim();
			if (target.length() != 0) {
				Pattern pattern = Pattern.compile(patternWeixin);
				Matcher matcher = pattern.matcher(target);
				result = matcher.matches();
			}
		}
		return result;
	}

	public static int getLuhnSum(String stPassed) {
		stPassed = stPassed.replaceAll("\\D", "");
		int len = stPassed.length();
		int sum = 0;
		int mul = 1;
		for (int i = len - 1; i >= 0; i--) {
			int digit = Character.digit(stPassed.charAt(i), 10);
			digit *= (mul == 1) ? mul++ : mul--;
			sum += (digit >= 10) ? (digit % 10) + 1 : digit;
		}
		return sum;
	}

	public static boolean isBankCardNumber(String stPassed) {
		if (isEmpty(stPassed))
			return false;
		String st = removeCharsInBag(stPassed, creditCardDelimiters);
		if (st.length() > 19 || st.length() < 5)
			return false;
		return ((getLuhnSum(st) % 10) == 0);
	}

	public static boolean isVisaCardNumber(String cc) {
		if (((cc.length() == 16) || (cc.length() == 13)) && (cc.substring(0, 1).equals("4")))
			return isBankCardNumber(cc);
		return false;
	}

	public static boolean isIdCardCN(String IDString) {
		String[] ValCodeArr = { "1", "0", "x", "9", "8", "7", "6", "5", "4", "3", "2" };
		String[] Wi = { "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2" };
		Hashtable<String, String> provinceCodeTable = new Hashtable<String, String>();
		provinceCodeTable.put("11", "北京");
		provinceCodeTable.put("12", "天津");
		provinceCodeTable.put("13", "河北");
		provinceCodeTable.put("14", "山西");
		provinceCodeTable.put("15", "内蒙古");
		provinceCodeTable.put("21", "辽宁");
		provinceCodeTable.put("22", "吉林");
		provinceCodeTable.put("23", "黑龙江");
		provinceCodeTable.put("31", "上海");
		provinceCodeTable.put("32", "江苏");
		provinceCodeTable.put("33", "浙江");
		provinceCodeTable.put("34", "安徽");
		provinceCodeTable.put("35", "福建");
		provinceCodeTable.put("36", "江西");
		provinceCodeTable.put("37", "山东");
		provinceCodeTable.put("41", "河南");
		provinceCodeTable.put("42", "湖北");
		provinceCodeTable.put("43", "湖南");
		provinceCodeTable.put("44", "广东");
		provinceCodeTable.put("45", "广西");
		provinceCodeTable.put("46", "海南");
		provinceCodeTable.put("50", "重庆");
		provinceCodeTable.put("51", "四川");
		provinceCodeTable.put("52", "贵州");
		provinceCodeTable.put("53", "云南");
		provinceCodeTable.put("54", "西藏");
		provinceCodeTable.put("61", "陕西");
		provinceCodeTable.put("62", "甘肃");
		provinceCodeTable.put("63", "青海");
		provinceCodeTable.put("64", "宁夏");
		provinceCodeTable.put("65", "新疆");
		provinceCodeTable.put("71", "台湾");
		provinceCodeTable.put("81", "香港");
		provinceCodeTable.put("82", "澳门");
		provinceCodeTable.put("91", "国外");

		String Ai = "";
		if (isEmpty(IDString)) {
			return false;
		}
		if (IDString.length() != 15 && IDString.length() != 18) {
			return false;
		}
		if (IDString.length() == 18) {
			Ai = IDString.substring(0, 17);
		} else if (IDString.length() == 15) {
			Ai = IDString.substring(0, 6) + "19" + IDString.substring(6, 15);
		}
		if (isDigit(Ai) == false) {
			return false;
		}
		String strYear = Ai.substring(6, 10);// 年份
		String strMonth = Ai.substring(10, 12);// 月份
		String strDay = Ai.substring(12, 14);// 日期
		String strDate = strYear + "-" + strMonth + "-" + strDay;
		Calendar calendar = Calendar.getInstance();
		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		try {
			if (isDate(strYear, strMonth, strDay) == false) {
				return false;
			} else if ((calendar.get(Calendar.YEAR) - Integer.parseInt(strYear)) > 150
					|| (calendar.getTime().getTime() - dateFormat.parse(strDate).getTime()) < 0) {
				return false;
			} else if (Integer.parseInt(strMonth) > 12 || Integer.parseInt(strMonth) == 0) {
				return false;
			} else if (Integer.parseInt(strDay) > 31 || Integer.parseInt(strDay) == 0) {
				return false;
			}
		} catch (Exception e) {
			return false;
		}
		if (provinceCodeTable.get(Ai.substring(0, 2)) == null) {
			return false;
		}
		if (IDString.length() == 18) {
			int TotalmulAiWi = 0;
			for (int i = 0; i < 17; i++) {
				TotalmulAiWi = TotalmulAiWi + Integer.parseInt(String.valueOf(Ai.charAt(i))) * Integer.parseInt(Wi[i]);
			}
			int modValue = TotalmulAiWi % 11;
			String strVerifyCode = ValCodeArr[modValue];
			Ai = Ai + strVerifyCode;
			if (Ai.equals(IDString) == false) {
				return false;
			}
		}
		return true;
	}

}
